<?php
namespace app\alipay\controller;

use tp5_lib\alipay\model\AlipayUserModel;
use tp5_lib\alipay\utility\Alipay;
use tp5_lib\user\extension\OutsideController;
use tp5_lib\install\logic\Module;
use think\Exception;
use tp5_lib\account\logic\AccountLogic;

/**
 * @property Alipay $alipay
 * @property \AopClient $client
 * @property AlipayUserModel $outside
 */
class IndexController extends OutsideController
{
    public function __get($name)
    {
        if($name === "outside"){
            if(empty($this->_outside)){
                $this->_outside=new AlipayUserModel();
            }
            return $this->_outside;
        }
        return parent::__get($name);
    }
    protected function initialize()
    {
        parent::initialize();
        $this->alipay=new Alipay();
        $this->client=$this->alipay->client;
    }
    public function index()
    {
        $this->markRedirectUrl();
        // $redirect_uri="http://www.airbaba.cn/custom/wechat_cb.php";
        $redirect_uri=$this->request->domain().url("receiveCode");
        $url=$this->alipay->getOAuthUrl($redirect_uri);
        $this->redirect($url);
    }
    public function receiveCode()
    {
        $code=input("auth_code");
        $request = new \AlipaySystemOauthTokenRequest();
        $request->setCode($code);
        $request->setGrantType("authorization_code");
        $response = $this->client->execute($request);
        if(empty($response->alipay_system_oauth_token_response)){
            $this->error($response->error_response->sub_msg);
        }
        $token = $response->alipay_system_oauth_token_response->access_token;
        $request = new \AlipayUserInfoShareRequest();
        $response = $this->client->execute($request,$token);
        if(empty($response->alipay_user_info_share_response->code) || $response->alipay_user_info_share_response->code !== "10000"){
            $this->error($response->alipay_user_info_share_response->sub_msg);
        }
        $user_info = (array)$response->alipay_user_info_share_response;
        $alipay_user_id = $user_info["alipay_user_id"] = $user_info["user_id"];
        unset($user_info["user_id"]);
        $model=new AlipayUserModel();
        $record=$model->db()->where(["alipay_user_id"=>$alipay_user_id])->find();
        if($record){
            $model->db()->where(["id"=>$record["id"]])->strict(false)->update($user_info);
            if($record["user_id"]){
                $user=$this->logic->doLogin($record["user_id"]);
                $this->loginRedirect($user);
            }
            else{
                $this->redirect("bindAccount",["id"=>$record["id"]]);
            }
        }
        else{
            $id=$model->db()->strict(false)->insertGetId($user_info);
            $this->redirect("bindAccount",["id"=>$id]);
        }
    }
    protected function convertUserInfo($data)
    {
        $sex = 0;
        if($data["gender"] === "m"){
            $sex = 1;
        }
        elseif($data["gender"] === "w"){
            $sex = 2;
        }
        $user=[
            "username"=>"ali_".$data["alipay_user_id"],
            "mobile"=>"",
            "email"=>"",
            "nickname"=>"支付宝用户".$data["alipay_user_id"],
            "avatar"=>"",
            "signature"=>"",
            "sex"=>$sex,
            "birthday"=>"",
            "url"=>"",
        ];
        return $user;
    }
    /**
     * 异步通知接口
     */
    public function onNotify()
    {
        $module=new Module();
        $record=[
            "post"=>$_POST,
            "result"=>"",
        ];
        register_shutdown_function(function()use($module,&$record){
            $record["output"]=ob_get_contents();
            $cwd=getcwd();
            chdir(__DIR__."/../../../public");
            $module->write("alipay_record_".time(),$record);
            chdir($cwd);
        });
        set_error_handler(function($errno, $errstr , $errfile, $errline)use(&$record){
            $record["error"]=[
                "type"=>"error",
                "errno"=>$errno, 
                "errstr"=>$errstr , 
                "errfile"=>$errfile, 
                "errline"=>$errline,
            ];
            echo "error";exit;
        });
        set_exception_handler(function($ex)use(&$record){
            /** @var \Exception $ex */
            $record["error"]=[
                "type"=>"exception",
                "message"=>$ex->getMessage(),
                "code"=>$ex->getCode(),
                "file"=>$ex->getFile(),
                "line"=>$ex->getLine(),
                "trace"=>$ex->getTrace(),
            ];
            echo "exception";exit;
        });
        
        $sign_type = empty($_POST["sign_type"]) ? "RSA" : $_POST["sign_type"];
        if(!$this->alipay->client->rsaCheckV1($_POST, NULL, $sign_type)){
            $record["error"]="验签失败";
            echo "fail";exit;
        }

        if($_POST["notify_type"] === "trade_status_sync"){
            if($_POST["trade_status"] === "TRADE_SUCCESS"){
                $account=new AccountLogic();
                if(!$account->success($_POST["out_trade_no"])){
                    $record["error"]="Account:".$account->getError();
                    echo "fail";exit;
                }
                $record["business"]="TRADE_SUCCESS";
            }
        }
        echo "success";exit;
    }
    /**
     * 支付回跳和查看结果地址
     */
    public function onReturn()
    {
        echo "ok";exit;
    }
}

